﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data.SqlClient;
using System.Text;
using System.Data;
using System.Collections;
using System.Linq;

namespace AccountDispatch
{
    class AccountFetcher
    {

        public Account[] GetAccounts(string UserId)
        {
            Collection<Account> ReturnValues = new Collection<Account>();

            DataTable dt = new DataTable();
            dt.TableName = "RESTful Service Example";
            dt = getFakeDbOrders();

	        foreach (DataRow row in dt.Rows) // Loop over the rows.
	        {
                    Account ReturnValue = new Account(); // do this to avoid a null pointer reference. 

                    ReturnValue.number = row["number"].ToString();
                    ReturnValue.name = row["name"].ToString();
                    ReturnValue.namenumber = row["namenumber"].ToString();
                    ReturnValues.Add(ReturnValue);
 
            }

            return (Account[])ReturnValues.ToArray();
        }

        public DataTable getFakeDbOrders()
        {
            DataTable dt = CreateNewDT();
            //Dim transferRow As DataRow = TransferDT.NewRow
            DataRow NewRow = dt.NewRow();
            NewRow["name"] = "HARRY AND DAVIDS DRUG ";
            NewRow["number"] = "10100198";
            NewRow["namenumber"] = "HARRY AND DAVIDS 10100198";
            dt.Rows.Add(NewRow);

            DataRow NewRow2 = dt.NewRow();
            NewRow2["name"] = "MEMORIAL MEDICAL CTR PHARMACY ";
            NewRow2["number"] = "10109952";
            NewRow2["namenumber"] = "MEMORIAL MEDICAL CTR PHARMACY 10109952";
            dt.Rows.Add(NewRow2);

            DataRow NewRow3 = dt.NewRow();
            NewRow3["name"] = "H LEE MOFFITT CANCER CTR (IV)";
            NewRow3["number"] = "40000782";
            NewRow3["namenumber"] = "H LEE MOFFITT CANCER CTR (IV) 40000782";
            dt.Rows.Add(NewRow3);

            return dt;
        }

        public DataTable CreateNewDT()
        {
            DataTable dt = new DataTable();
            DataColumn Name = new DataColumn("name", typeof(string));
            DataColumn Number = new DataColumn("number", typeof(string));
            DataColumn NameNumber = new DataColumn("namenumber", typeof(string));
            dt.Columns.Add(Name);
            dt.Columns.Add(Number);
            dt.Columns.Add(NameNumber);
            return dt;
        }

        // fully databased version. not useful for demos.
        public Account[] GetAccountsDB(string UserId)
        {

            Collection<Account> ReturnValues = new Collection<Account>();
            
            String strConnFdb = ConfigurationManager.ConnectionStrings["OrderManagementString"].ConnectionString;
            SqlConnection sqlConnFdb = new SqlConnection(strConnFdb);
            SqlCommand myCommand = new SqlCommand("exec [orm].[spAccountSel] '" + UserId + "'", sqlConnFdb);

            try
            {
                sqlConnFdb.Open();
                SqlDataReader objReader = myCommand.ExecuteReader();
                while (objReader.Read())
                {
                    Account ReturnValue = new Account(); // do this to avoid a null pointer reference. 

                    ReturnValue.number = objReader["number"].ToString();
                    ReturnValue.name = objReader["name"].ToString();
                    ReturnValue.namenumber = objReader["namenumber"].ToString();
                    ReturnValues.Add(ReturnValue);
                    //yield ReturnValues;
                    //yield return ReturnValues;
                }
            }
            finally
            {
                sqlConnFdb.Close();
                myCommand.Dispose();
            }

            return (Account[])ReturnValues.ToArray();

        }

        internal Message AddAccount(string UserId, string name, string number)
        {
            Message ReturnValue = new Message();
            ReturnValue.message = "Item added successfully.";
            return ReturnValue;
        }

        internal Message DeleteAccount(string UniqueId)
        {
            Message ReturnValue = new Message();
            ReturnValue.message = "Item deleted successfully.";
            return ReturnValue;
        }

        internal Message UpdateAccount(string UserId, string name, string number)
        {
            Message ReturnValue = new Message();
            ReturnValue.message = "Item updated successfully.";
            return ReturnValue;
        }

        // this is legacy code before we figured out how to return the exact # of items selected.
        // can't really use this code, but it works. 
        public int MaxNumberOfAccount = 100;

        public Account[] GetAccountsTheHardWay(string UserId)
        {
            Account[] ReturnValues = new Account[MaxNumberOfAccount]; // dunno a better way to do this. C# does not allow dynamic resizing of native arrays. 

            int count = 0;
            // call the database and return values.
            String strConnFdb = ConfigurationManager.ConnectionStrings["OrderManagementString"].ConnectionString;
            SqlConnection sqlConnFdb = new SqlConnection(strConnFdb);
            SqlCommand myCommand = new SqlCommand("exec [orm].[spAccountSel] '" + UserId + "'", sqlConnFdb);

            try
            {
                sqlConnFdb.Open();
                SqlDataReader objReader = myCommand.ExecuteReader();
                
                while (objReader.Read())
                {
                    //AccountAndName thisItem = new AccountAndName();
                    //AccountAndName[] ReturnValues.Accounts[count] = new AccountAndName[0]; // this does not work.
                    //countAndName ReturnValues[count] = new AccountAndName();

                    ReturnValues[count] = new Account(); // do this to avoid a null pointer reference. 

                    ReturnValues[count].number = objReader["number"].ToString();
                    ReturnValues[count].name = objReader["name"].ToString();
                    ReturnValues[count].namenumber = objReader["namenumber"].ToString();
                    //ReturnValues[count].MessageValue = "";

                    count++;
                }
            }
            catch (Exception ex)
            {
                ReturnValues[0].name = ex.Message;
            }
            finally
            {
                sqlConnFdb.Close();
                myCommand.Dispose();
            }

            return (AccountDispatch.Account[])ResizeArray(ReturnValues, count); // resize the array.
        }

        // dunno a better way to do this. C# does not allow dynamic resizing of native arrays. 
        // Got this from http://www.source-code.biz/snippets/csharp/1.htm
        public static System.Array ResizeArray(System.Array oldArray, int newSize)
        {
            int oldSize = oldArray.Length;
            System.Type elementType = oldArray.GetType().GetElementType();
            System.Array newArray = System.Array.CreateInstance(elementType, newSize);
            int preserveLength = System.Math.Min(oldSize, newSize);
            if (preserveLength > 0)
                System.Array.Copy(oldArray, newArray, preserveLength);
            return newArray;
        }

    }
}
